package edu.bbu.commonproject.desktop.gui.controller.concrete;

import java.awt.Desktop;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;

import edu.bbu.commonproject.desktop.client.exceptions.DataBaseErrorException;
import edu.bbu.commonproject.desktop.client.exceptions.DirectoryOperationException;
import edu.bbu.commonproject.desktop.client.exceptions.FileDownloadException;
import edu.bbu.commonproject.desktop.client.exceptions.FileOperationException;
import edu.bbu.commonproject.desktop.client.exceptions.FileUploadException;
import edu.bbu.commonproject.desktop.client.exceptions.NoConnectionException;
import edu.bbu.commonproject.desktop.client.exceptions.TransferInterruptedException;
import edu.bbu.commonproject.desktop.client.exceptions.WrongUserDataException;
import edu.bbu.commonproject.desktop.client.model.DirectoryPOJO;
import edu.bbu.commonproject.desktop.client.model.FilePOJO;
import edu.bbu.commonproject.desktop.client.services.DirectoryCLTServices;
import edu.bbu.commonproject.desktop.client.utils.FileTransferObserver;
import edu.bbu.commonproject.desktop.gui.controller.BaseController;
import edu.bbu.commonproject.desktop.gui.controller.utils.UserProperties;
import edu.bbu.commonproject.desktop.gui.controller.utils.dnd.FileInformation;
import edu.bbu.commonproject.desktop.gui.controller.utils.dnd.TransferableFile;
import edu.bbu.commonproject.desktop.gui.view.FileListInterface;
import edu.bbu.commonproject.desktop.gui.view.swing.base.BaseFrame;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.LocalFileListPanel;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.ServerFileListPanel;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components.LDirectory;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components.LFile;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components.LParentDirectory;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components.LVFile;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components.Listable;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.utils.DeleteDialog;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.utils.DirectoryCreator;
import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.utils.GeneralDialog;
import edu.bbu.commonproject.desktop.gui.view.swing.file.traffic.ListItem;
import edu.bbu.commonproject.desktop.gui.view.swing.file.traffic.ScrollList;
import edu.bbu.commonproject.desktop.gui.view.swing.utils.AboutFrame;
import edu.bbu.commonproject.desktop.gui.view.swing.utils.HelpFrame;
import edu.bbu.commonproject.desktop.gui.view.swing.utils.Tray;

/**
 * The file list GUI component controller.
 */
public class FileListController extends BaseController
{
	/** The one way sync. */
	private static final int ONE_WAY_SYNC = 1;
	
	/** The two way sync. */
	private static final int TWO_WAY_SYNC = 2;
	
	/** The manual sync demand is cleared. */
	private static final int MANUAL_SYNC_CLEAR = 1;
	
	/** The manual sync demand is fired up. */
	private static final int MANUAL_SYNC_DEMAND = 0;
	
	/** The sync check period in seconds. */
	private static final int SYNC_CHECK_PERIOD = 180;
	
	/** The sync check period in seconds. */
	private static final int TRANSFER_WAIT = 1;
	
	/** The root directory. */
	private static final String ROOT_DIRECTORY = "<RT>";
	
	/** The parent directory. */
	private static final String PARENT_DIRECTORY = "<BK>";
	
	/** The base frame controller. */
	private BaseFrameController baseFrameController;
	
	/** The file list interface. */
	private FileListInterface fileListInterface;
	
	/** The drag gesture listener. */
	private DragGestureListener localFileDragGestureListener;
	
	/** The drag gesture listener. */
	private DragGestureListener localDirectoryDragGestureListener;
	
	/** The drag gesture listener. */
	private DragGestureListener serverFileDragGestureListener;
	
	/** The drag gesture listener. */
	private DragGestureListener serverFileVersionDragGestureListener;
	
	/** The drag gesture listener. */
	private DragGestureListener serverDirectoryDragGestureListener;
	
	/** The drop target listener. */
	private DropTargetListener localFileDropTargetListener;
	
	/** The drop target listener. */
	private DropTargetListener localDirectoryDropTargetListener;
	
	/** The drop target listener. */
	private DropTargetListener serverFileDropTargetListener;
	
	/** The drop target listener. */
	private DropTargetListener serverDirectoryDropTargetListener;
	
	/** The mouse adapter for the local files. */
	private MouseAdapter localFileMouseAdapter;
	
	/** The mouse adapter for the local directories. */
	private MouseAdapter localDirectoryMouseAdapter;
	
	/** The mouse adapter for the local back to parent directory. */
	private MouseAdapter localParentDirectoryMouseAdapter;
	
	/** The mouse adapter for the server files. */
	private MouseAdapter serverFileMouseAdapter;
	
	/** The mouse adapter for the server directories. */
	private MouseAdapter serverDirectoryMouseAdapter;
	
	/** The mouse adapter for the server back to parent directory. */
	private MouseAdapter serverParentDirectoryMouseAdapter;	
	
	/** The synchronization lock. */
	private Object syncLock;
	
	/** The synchronization thread. */
	private Thread syncThread;
	
	/** The user asked for manual synchronization. */
	private int manualSyncDemand;
	
	/** The manual sync demand lock. */
	private Object manualSyncDemandLock;
	
	/** The user is logged in or not. */
	private boolean isUserLoggedIn;
	
	/** The login lock. */
	private Object loginLock;
	
	/**
	 * The file list controller's constructor.
	 * @param fileListInterface the GUI elements interface.
	 */
	public FileListController(BaseFrameController baseFrameController, FileListInterface fileListInterface) 
	{
		this.baseFrameController = baseFrameController;
		this.fileListInterface = fileListInterface;
		
		setListeners();
		
		syncLock = new Object();
		manualSyncDemandLock = new Object();
		setManualSyncDemand(MANUAL_SYNC_CLEAR);
		
		loginLock = new Object();
		setUserLoggedIn(false);	
		
		((LocalFileListPanel)fileListInterface.getLocalFileList()).addDropTargetListener(localFileDropTargetListener);
		((ServerFileListPanel)fileListInterface.getServerFileList()).addDropTargetListener(serverFileDropTargetListener);
	}
	
	/**
	 * Setting on all of the listeners.
	 */
	private void setListeners()
	{
		setDragListeners();
		setMenuBarListeners();
		setFileControlListeners();
		setNavigationMenuListeners();
		setTransferManagerListeners();
		setFileAndDirectoryListeners();
		setUploadAndDownloadListeners();
		setTrayPopupMenuListesners();
	}
	
	/**
	 * Setting on the drag listeners.
	 */
	private void setDragListeners()
	{
		//Drag source gesture listener for local files.
		localFileDragGestureListener = new DragGestureListener()
		{
			public void dragGestureRecognized(DragGestureEvent e)
			{
				Listable sourceComponent = (Listable) e.getComponent();
				
				FileInformation fileInformation = new FileInformation();
				fileInformation.setType(FileInformation.FILE_TYPE);
				fileInformation.setSource(FileInformation.LOCAL_SOURCE);
				fileInformation.setName(sourceComponent.getItemName());
				fileInformation.setPath(sourceComponent.getFileLister().getCurrentPath());
				
				Transferable transferable = new TransferableFile(fileInformation);
				
				if(DragSource.isDragImageSupported())
				{
					e.startDrag(null, sourceComponent.getImage(), new Point(32, 40), transferable, new DragSourceAdapter(){ });
				}
				else 
				{
					e.startDrag(null, transferable);
				}
			}
		};
		
		//Drag source gesture listener for local directoryes.
		localDirectoryDragGestureListener = new DragGestureListener()
		{
			public void dragGestureRecognized(DragGestureEvent e)
			{
				Listable sourceComponent = (Listable) e.getComponent();
				
				FileInformation fileInformation = new FileInformation();
				fileInformation.setType(FileInformation.DIRECTORY_TYPE);
				fileInformation.setSource(FileInformation.LOCAL_SOURCE);
				fileInformation.setName(sourceComponent.getItemName());
				fileInformation.setPath(sourceComponent.getFileLister().getCurrentPath());
				
				Transferable transferable = new TransferableFile(fileInformation);
				
				if(DragSource.isDragImageSupported())
				{
					e.startDrag(null, sourceComponent.getImage(), new Point(32, 40), transferable, new DragSourceAdapter(){ });
				}
				else 
				{
					e.startDrag(null, transferable);
				}
			}
		};
		
		//Drag source gesture listener for server files.
		serverFileDragGestureListener = new DragGestureListener()
		{
			public void dragGestureRecognized(DragGestureEvent e)
			{
				Listable sourceComponent = (Listable) e.getComponent();
				
				FileInformation fileInformation = new FileInformation();
				fileInformation.setType(FileInformation.FILE_TYPE);
				fileInformation.setSource(FileInformation.SERVER_SOURCE);
				fileInformation.setName(sourceComponent.getItemName());
				fileInformation.setPath(sourceComponent.getFileLister().getCurrentPath());
				
				Transferable transferable = new TransferableFile(fileInformation);
				
				if(DragSource.isDragImageSupported())
				{
					e.startDrag(null, sourceComponent.getImage(), new Point(32, 40), transferable, new DragSourceAdapter(){ });
				}
				else 
				{
					e.startDrag(null, transferable);
				}
			}
		};
		
		//Drag source gesture listener for server version files.
		serverFileVersionDragGestureListener = new DragGestureListener()
		{
			public void dragGestureRecognized(DragGestureEvent e)
			{
				Listable sourceComponent = (Listable) e.getComponent();
				
				int version = ((LVFile) sourceComponent).getVersionNumber();
				String name = stringFormatter.getLastDirectoryInPath(sourceComponent.getFileLister().getCurrentPath(), DirectoryCLTServices.separator);
				String path = stringFormatter.parentDirectoryFormat(sourceComponent.getFileLister().getCurrentPath(), DirectoryCLTServices.separator);
				
				FileInformation fileInformation = new FileInformation();
				fileInformation.setType(FileInformation.FILE_VERSION_TYPE);
				fileInformation.setSource(FileInformation.SERVER_SOURCE);
				fileInformation.setName(name);
				fileInformation.setPath(path);
				fileInformation.setVersion(version);
				
				Transferable transferable = new TransferableFile(fileInformation);
				
				if(DragSource.isDragImageSupported())
				{
					e.startDrag(null, sourceComponent.getImage(), new Point(32, 40), transferable, new DragSourceAdapter(){ });
				}
				else 
				{
					e.startDrag(null, transferable);
				}
			}
		};
		
		//Drag source gesture listener for server directoryes.
		serverDirectoryDragGestureListener = new DragGestureListener()
		{
			public void dragGestureRecognized(DragGestureEvent e)
			{
				Listable sourceComponent = (Listable) e.getComponent();
				
				FileInformation fileInformation = new FileInformation();
				fileInformation.setType(FileInformation.DIRECTORY_TYPE);
				fileInformation.setSource(FileInformation.SERVER_SOURCE);
				fileInformation.setName(sourceComponent.getItemName());
				fileInformation.setPath(sourceComponent.getFileLister().getCurrentPath());
				
				Transferable transferable = new TransferableFile(fileInformation);
				
				if(DragSource.isDragImageSupported())
				{
					e.startDrag(null, sourceComponent.getImage(), new Point(32, 40), transferable, new DragSourceAdapter(){ });
				}
				else 
				{
					e.startDrag(null, transferable);
				}
			}
		};
		
		//Drop target listener for local files (it use the local file list panel too).
		localFileDropTargetListener = new DropTargetAdapter()
		{
			public void drop(DropTargetDropEvent e)
			{
				if(e.isDataFlavorSupported(TransferableFile.fileFlavor))
				{
					e.acceptDrop(DnDConstants.ACTION_COPY);
					
					try
					{
						final FileInformation sourceFile = (FileInformation) e.getTransferable().getTransferData(TransferableFile.fileFlavor);
						final LocalFileListPanel localFileListPanel = ((LocalFileListPanel) fileListInterface.getLocalFileList());
									
						if(sourceFile.getSource() == FileInformation.SERVER_SOURCE)
						{
							new Thread(new Runnable()
							{
								public void run()
								{								
									if(!localFileListPanel.isCurrentPathCleared())
									{
										switch (sourceFile.getType())
										{
											case FileInformation.FILE_TYPE:
											{
												int lastFileVersion = getLastFileVersion(sourceFile.getPath(), sourceFile.getName());
												
												if(lastFileVersion == -1)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File not found, probably already deleted!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
													
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															updateServerDirectoryContent();
															updateLocalDirectoryContent();
														}
													});
													
													return;
												}
												
												boolean success = downloadFile(localFileListPanel.getCurrentPath(), sourceFile.getPath(), sourceFile.getName(), lastFileVersion);
											
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
											
											case FileInformation.DIRECTORY_TYPE:
											{
												boolean success = downloadDirectory(localFileListPanel.getCurrentPath(), sourceFile.getPath(), sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "Directory download error", "Directory download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
											
											case FileInformation.FILE_VERSION_TYPE:
											{
												boolean success = downloadFile(localFileListPanel.getCurrentPath(), sourceFile.getPath(), sourceFile.getName(), sourceFile.getVersion());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
										}
										
										SwingUtilities.invokeLater(new Runnable()
										{
											public void run()
											{
												updateServerDirectoryContent();
												updateLocalDirectoryContent();
											}
										});
									}
									else 
									{
										SwingUtilities.invokeLater(new Runnable()
										{
											public void run()
											{
												new GeneralDialog(baseFrameController.getBaseFrame(), "Download warning", "Please select a valid download directory!", GeneralDialog.ERROR_DIALOG).showDialog();
											}
										});
									}
								}
								
							}).start();
						}
						
						e.dropComplete(true);
						return;
					}
					catch (UnsupportedFlavorException | IOException ex)
					{
						e.rejectDrop();
					}
				}
				else 
				{
					e.rejectDrop();
				}
			}
			
			
		};
		
		//Drop targel listener for local directoryes (needed to put the dropped item into directory).
		localDirectoryDropTargetListener = new DropTargetAdapter()
		{
			public void drop(final DropTargetDropEvent e)
			{
				if(e.isDataFlavorSupported(TransferableFile.fileFlavor))
				{
					e.acceptDrop(DnDConstants.ACTION_COPY);
					
					try
					{
						final FileInformation sourceFile = (FileInformation) e.getTransferable().getTransferData(TransferableFile.fileFlavor);
						final LocalFileListPanel localFileListPanel = ((LocalFileListPanel) fileListInterface.getLocalFileList());
									
						if(sourceFile.getSource() == FileInformation.SERVER_SOURCE)
						{
							new Thread(new Runnable()
							{
								public void run()
								{	
									String localPath;
									
									if(!localFileListPanel.isCurrentPathCleared())
									{
										localPath = localFileListPanel.getCurrentPath() + ((LDirectory) e.getDropTargetContext().getComponent()).getItemName() + File.separator;
									}
									else 
									{
										localPath = ((LDirectory) e.getDropTargetContext().getComponent()).getItemName();
									}
					
									switch (sourceFile.getType())
									{
										case FileInformation.FILE_TYPE:
										{
											int lastFileVersion = getLastFileVersion(sourceFile.getPath(), sourceFile.getName());
											
											if(lastFileVersion == -1)
											{
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File not found, probably already deleted!", GeneralDialog.ERROR_DIALOG).showDialog();
													}
												});
												
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														updateServerDirectoryContent();
														updateLocalDirectoryContent();
													}
												});
												
												return;
											}
											
											boolean success = downloadFile(localPath, sourceFile.getPath(), sourceFile.getName(), lastFileVersion);
										
											if(!success)
											{
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
													}
												});
											}
											
										}break;
										
										case FileInformation.DIRECTORY_TYPE:
										{
											boolean success = downloadDirectory(localPath, sourceFile.getPath(), sourceFile.getName());
											
											if(!success)
											{
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														new GeneralDialog(baseFrameController.getBaseFrame(), "Directory download error", "Directory download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
													}
												});
											}
											
										}break;
										
										case FileInformation.FILE_VERSION_TYPE:
										{
											boolean success = downloadFile(localPath, sourceFile.getPath(), sourceFile.getName(), sourceFile.getVersion());
											
											if(!success)
											{
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
													}
												});
											}
											
										}break;
									}
									
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											updateServerDirectoryContent();
											updateLocalDirectoryContent();
										}
									});
								}
								
							}).start();
						}
						
						e.dropComplete(true);
						return;
					}
					catch (UnsupportedFlavorException | IOException ex)
					{
						e.rejectDrop();
					}
				}
				else 
				{
					e.rejectDrop();
				}
			}
			
			public void dragEnter(DropTargetDragEvent e)
			{
				Listable listable = (Listable) e.getDropTargetContext().getComponent();
				
				if(listable.getClass() == LDirectory.class)
				{
					listable.setSelected();
				}
			}
			
			public void dragExit(DropTargetEvent e)
			{
				Listable listable = (Listable) e.getDropTargetContext().getComponent();
				
				if(listable.getClass() == LDirectory.class)
				{
					listable.setUnSelected();
				}
			}
		};
		
		//Drop targel listener for server files (it uses the server file list panel and the file versions too).
		serverFileDropTargetListener =  new DropTargetAdapter()
		{
			public void drop(DropTargetDropEvent e)
			{
				if(e.isDataFlavorSupported(TransferableFile.fileFlavor))
				{
					e.acceptDrop(DnDConstants.ACTION_COPY);
					
					try
					{
						final FileInformation sourceFile = (FileInformation) e.getTransferable().getTransferData(TransferableFile.fileFlavor);
						final ServerFileListPanel serverFileListPanel = ((ServerFileListPanel) fileListInterface.getServerFileList());
									
						if(sourceFile.getSource() == FileInformation.LOCAL_SOURCE)
						{
							new Thread(new Runnable()
							{
								public void run()
								{	
									if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
									{
										switch (sourceFile.getType())
										{
											case FileInformation.FILE_TYPE:
											{
												boolean success = uploadFile(sourceFile.getPath(), serverFileListPanel.getCurrentPath(), sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File upload error", "File upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
											
											case FileInformation.DIRECTORY_TYPE:
											{
												boolean success = uploadDirectory(sourceFile.getPath(), serverFileListPanel.getCurrentPath(), sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "Directry upload error", "Directry upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
										}
									}
									else 
									{		
										if(sourceFile.getType() == FileInformation.FILE_TYPE)
										{
											String localFileName = sourceFile.getName();
											String serverFileName = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
											
											if(localFileName.equals(serverFileName))
											{
												String serverPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
												
												boolean success = uploadFile(sourceFile.getPath(), serverPath, sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File upload error", "File upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
											}
											else 
											{
												SwingUtilities.invokeLater(new Runnable()
												{
													public void run()
													{
														new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "To a new version, file names must correspond!", GeneralDialog.WARNING_DIALOG).showDialog();
													}
												});
											}
										}
										else 
										{
											SwingUtilities.invokeLater(new Runnable()
											{
												public void run()
												{
													new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "Please select a file!", GeneralDialog.WARNING_DIALOG).showDialog();
												}
											});
										}
									}
									
									
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											updateServerDirectoryContent();
											updateLocalDirectoryContent();
										}
									});
								}
								
							}).start();
						}
						
						e.dropComplete(true);
						return;
					}
					catch (UnsupportedFlavorException | IOException ex)
					{
						e.rejectDrop();
					}
				}
				else 
				{
					e.rejectDrop();
				}
			}
		};
		
		//Drop targel listener for server directoryes (needed to put the dropped item into directory).
		serverDirectoryDropTargetListener =  new DropTargetAdapter()
		{
			public void drop(final DropTargetDropEvent e)
			{
				if(e.isDataFlavorSupported(TransferableFile.fileFlavor))
				{
					e.acceptDrop(DnDConstants.ACTION_COPY);
					
					try
					{
						final FileInformation sourceFile = (FileInformation) e.getTransferable().getTransferData(TransferableFile.fileFlavor);
						final ServerFileListPanel serverFileListPanel = ((ServerFileListPanel) fileListInterface.getServerFileList());
									
						if(sourceFile.getSource() == FileInformation.LOCAL_SOURCE)
						{
							new Thread(new Runnable()
							{
								public void run()
								{	
									String serverPath = serverFileListPanel.getCurrentPath() + ((LDirectory) e.getDropTargetContext().getComponent()).getItemName() + DirectoryCLTServices.separator;
									
									if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
									{
										switch (sourceFile.getType())
										{
											case FileInformation.FILE_TYPE:
											{
												boolean success = uploadFile(sourceFile.getPath(), serverPath, sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "File upload error", "File upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
											
											case FileInformation.DIRECTORY_TYPE:
											{
												boolean success = uploadDirectory(sourceFile.getPath(), serverPath, sourceFile.getName());
												
												if(!success)
												{
													SwingUtilities.invokeLater(new Runnable()
													{
														public void run()
														{
															new GeneralDialog(baseFrameController.getBaseFrame(), "Directry upload error", "Directry upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
														}
													});
												}
												
											}break;
										}
									}									
									
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											updateServerDirectoryContent();
											updateLocalDirectoryContent();
										}
									});
								}
								
							}).start();
						}
						
						e.dropComplete(true);
						return;
					}
					catch (UnsupportedFlavorException | IOException ex)
					{
						e.rejectDrop();
					}
				}
				else 
				{
					e.rejectDrop();
				}
			}
			
			public void dragEnter(DropTargetDragEvent e)
			{
				Listable listable = (Listable) e.getDropTargetContext().getComponent();
				
				if(listable.getClass() == LDirectory.class)
				{
					listable.setSelected();
				}
			}
			
			public void dragExit(DropTargetEvent e)
			{
				Listable listable = (Listable) e.getDropTargetContext().getComponent();
				
				if(listable.getClass() == LDirectory.class)
				{
					listable.setUnSelected();
				}
			}
		};
	}
	
	/**
	 * Setting on the file and directory listeners.
	 */
	private void setFileAndDirectoryListeners()
	{
		//The local file mosuse adapter.
		localFileMouseAdapter = new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{	
				if(e.getClickCount() == 2)
				{
					LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
					
					boolean success = openLocalFile(localFileListPanel.getCurrentPath(), ((LFile) e.getSource()).getItemName());
				
					if(!success)
					{
						updateLocalDirectoryContent();
						new GeneralDialog(baseFrameController.getBaseFrame(), "Opening file", "Can't open this file!", GeneralDialog.WARNING_DIALOG).showDialog();
					}
				}
			}
		};
		
		//The directory click handle.
		localDirectoryMouseAdapter = new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				if(e.getClickCount() == 2)
				{
					showLocalDirectoryContent(((LDirectory) e.getSource()).getItemName());
					
				}
			}
		};
		
		//The parent directory click handle.
		localParentDirectoryMouseAdapter = new MouseAdapter()
		{			
			public void mousePressed(MouseEvent e)
			{
				showLocalDirectoryContent(PARENT_DIRECTORY);
			}
		};
		
		//The server file mouse adapter.
		serverFileMouseAdapter = new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				if(e.getClickCount() == 2)
				{
					displayServerFileVersions(((LFile) e.getSource()).getItemName());
				}
			}
		};
		
		//The directory click handle.
		serverDirectoryMouseAdapter = new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				if(e.getClickCount() == 2)
				{
					showServerDirectoryContent(((LDirectory) e.getSource()).getItemName());
				}
			}
		};
		
		//The parent directory click handle.
		serverParentDirectoryMouseAdapter = new MouseAdapter()
		{			
			public void mousePressed(MouseEvent e)
			{
				showServerDirectoryContent(PARENT_DIRECTORY);
			}
		};
	}
	
	/**
	 * Setting on the upload and download listeners.
	 */
	private void setUploadAndDownloadListeners()
	{
		((JButton) fileListInterface.getUploadButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{				
				uploadSelectedFile();
			}
		});
		
		((JButton) fileListInterface.getDownloadButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{ 
				downloadSelectedFile();
			}
		});
	}
	
	/**
	 * Setting on the file controller listeners.
	 */
	private void setFileControlListeners()
	{
		//The local control panel back to parrent.
		((JButton) fileListInterface.getLocalBackToParrentButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
				
				if(!localFileListPanel.isCurrentPathCleared())
				{
					showLocalDirectoryContent(PARENT_DIRECTORY);
				}
			}
		});
		
		//The server control panel back to parrent.
		((JButton) fileListInterface.getServerBackToParrentButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
				
				if(!serverFileListPanel.isCurrentPathCleared())
				{
					showServerDirectoryContent(PARENT_DIRECTORY);
				}
			}
		});
		
		//The local directory creator button handle on the controller.
		((JButton) fileListInterface.getCreateLocalDirectoryButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{	
				LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
				
				if(!localFileListPanel.isCurrentPathCleared())
				{
					DirectoryCreator directoryCreator = new DirectoryCreator(baseFrameController.getBaseFrame());
					directoryCreator.showDialog();
					
					if(directoryCreator.getAnswer() == DirectoryCreator.CREATE_ANSWER)
					{
						if(!stringFormatter.isValiadDirectoryName(directoryCreator.getDirectoryName()))
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Directory name error", "Invalid directory name!", GeneralDialog.ERROR_DIALOG).showDialog();
							return;
						}
						
						boolean success = makeNewLocalDirectory(localFileListPanel.getCurrentPath(), directoryCreator.getDirectoryName());
						
						if(!success)
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Directory error", "Directory already exist!", GeneralDialog.ERROR_DIALOG).showDialog();
							return;
						}
						
						updateLocalDirectoryContent();
					}
				}
			}
		});
		
		//The server directory creator button handle on the controller.
		((JButton) fileListInterface.getCreateServerDirectoryButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
				
				if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
				{
					DirectoryCreator directoryCreator = new DirectoryCreator(baseFrameController.getBaseFrame());
					directoryCreator.showDialog();
					
					if(directoryCreator.getAnswer() == DirectoryCreator.CREATE_ANSWER)
					{
						if(!stringFormatter.isValiadDirectoryName(directoryCreator.getDirectoryName()))
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Directory name error", "Invalid directory name!", GeneralDialog.ERROR_DIALOG).showDialog();
							return;
						}
						
						boolean success = makeNewServerDirectory(serverFileListPanel.getCurrentPath(), directoryCreator.getDirectoryName());
						
						if(!success)
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Directory error", "Directory already exist!", GeneralDialog.ERROR_DIALOG).showDialog();
							return;
						}
						
						updateServerDirectoryContent();
					}
				}
				else 
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Directory warning", "Can't create directory in file versions view!", GeneralDialog.WARNING_DIALOG).showDialog();
				}
			}
		});
		
		//The local control panel delete button.
		((JButton) fileListInterface.getDeleteLocalSelectedItemButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
	
				if(!localFileListPanel.isCurrentPathCleared())
				{
					Object selectedItem = localFileListPanel.getSelectedListItem();
					
					if(selectedItem != null)
					{
						DeleteDialog deleteDialog = new DeleteDialog(baseFrameController.getBaseFrame());
						deleteDialog.showDialog();
						
						if(deleteDialog.getAnswer() == DeleteDialog.DELETE_ANSWER)
						{
							if(selectedItem.getClass() == LDirectory.class)
							{
								LDirectory directory = (LDirectory) selectedItem;
								boolean success = deleteLocalDirectory(localFileListPanel.getCurrentPath(), directory.getItemName());
								
								if(!success)
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Delete error", "Directory can't be deleted!", GeneralDialog.WARNING_DIALOG).showDialog();	
								}
								
								updateLocalDirectoryContent();
							}
							else if(selectedItem.getClass() == LFile.class)
							{
								LFile file = (LFile) selectedItem;
								boolean success = deleteLocalFile(localFileListPanel.getCurrentPath(), file.getItemName());
								
								if(!success)
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Delete error", "File can't be deleted!", GeneralDialog.WARNING_DIALOG).showDialog();	
								}
								
								updateLocalDirectoryContent();
							}
						}
					}
					else 
					{
						new GeneralDialog(baseFrameController.getBaseFrame(), "Delete warning", "Please select a file or a directory!", GeneralDialog.WARNING_DIALOG).showDialog();		
					}
				}
			}
		});
		
		//The server control panel delete button.
		((JButton) fileListInterface.getDeleteServerSelectedItemButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
			
				Object selectedItem = serverFileListPanel.getSelectedListItem();
				
				if(selectedItem != null)
				{
					DeleteDialog deleteDialog = new DeleteDialog(baseFrameController.getBaseFrame());
					deleteDialog.showDialog();
					
					if(deleteDialog.getAnswer() == DeleteDialog.DELETE_ANSWER)
					{					
						if(selectedItem.getClass() == LDirectory.class)
						{
							LDirectory directory = (LDirectory) selectedItem;
							boolean success = deleteServerDirectory(serverFileListPanel.getCurrentPath(), directory.getItemName());
							
							if(!success)
							{
								new GeneralDialog(baseFrameController.getBaseFrame(), "Delete error", "Directory can't be deleted!", GeneralDialog.WARNING_DIALOG).showDialog();	
							}
						}
						else if(selectedItem.getClass() == LFile.class)
						{
							LFile file = (LFile) selectedItem;
							
							boolean success = deleteServerFile(serverFileListPanel.getCurrentPath(), file.getItemName());
							
							if(!success)
							{
								new GeneralDialog(baseFrameController.getBaseFrame(), "Delete error", "File can't be deleted!", GeneralDialog.WARNING_DIALOG).showDialog();	
							}
						}
						else if(selectedItem.getClass() == LVFile.class)
						{
							LVFile file = (LVFile) selectedItem;
							
							String fileName = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
							String parrentPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
							
							boolean success = deleteServerFileVersion(parrentPath, fileName, file.getVersionNumber());
							
							if(!success)
							{
								new GeneralDialog(baseFrameController.getBaseFrame(), "Delete error", "File can't be deleted!", GeneralDialog.WARNING_DIALOG).showDialog();	
							}
						}
						
						updateServerDirectoryContent();
					}
				}
				else 
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Delete warning", "Please select a file or a directory!", GeneralDialog.WARNING_DIALOG).showDialog();		
				}
			}
		});
		
		//The local control panel refresh.
		((JButton) fileListInterface.getLocalUpdateDirectoryContentButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				updateLocalDirectoryContent();
			}
		});
		
		//The server control panel refresh.
		((JButton) fileListInterface.getServerUpdateDirectoryContentButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				updateServerDirectoryContent();
			}
		});
		
	}

	/**
	 * Setting on the transfer and manager listeners.
	 */
	private void setTransferManagerListeners()
	{
		((JButton) fileListInterface.getStartButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				ScrollList scrollList = (ScrollList) fileListInterface.getBottomScrollList();
				ListItem selectedItem = scrollList.getSelectedItem();
				
				if(selectedItem != null )
				{
					selectedItem.startTransfer();
				}
			}
		});
		
		((JButton) fileListInterface.getPauseButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				ScrollList scrollList = (ScrollList) fileListInterface.getBottomScrollList();
				ListItem selectedItem = scrollList.getSelectedItem();
				
				if(selectedItem != null)
				{
					selectedItem.pauseTransfer();
				}
			}
		});
		
		((JButton) fileListInterface.getStopButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				ScrollList scrollList = (ScrollList) fileListInterface.getBottomScrollList();
				ListItem selectedItem = scrollList.getSelectedItem();
				
				if(selectedItem != null)
				{
					selectedItem.stopTransfer();
				}
			}
		});
		
		((JButton) fileListInterface.getRemoveButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				ScrollList scrollList = (ScrollList) fileListInterface.getBottomScrollList();
				ListItem selectedItem = scrollList.getSelectedItem();
				
				if(selectedItem != null)
				{
					selectedItem.stopTransfer();
					scrollList.removeItem(selectedItem);
				}
			}
		});
	}
	
	/**
	 * Setting on the navigation menu listeners.
	 */
	private void setNavigationMenuListeners()
	{
		((JButton) fileListInterface.getLogoutButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				logoutUser();
			}
		});
		
		((JButton) fileListInterface.getSyncButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{	
				startManualSynchronization();
			}
		});
		
		((JButton) fileListInterface.getSetupButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadSyncSetupView();
			}
		});
		
		((JButton) fileListInterface.getHelpButton()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				new HelpFrame();
			}
		});
	}
	
	/**
	 * Setting on the menu bar listeners.
	 */
	private void setMenuBarListeners()
	{
		((JMenuItem) fileListInterface.getLogoutMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				logoutUser();
			}
		});
		
		((JMenuItem) fileListInterface.getExitMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
		
		((JMenuItem) fileListInterface.getUploadMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				uploadSelectedFile();
			}
		});
		
		((JMenuItem) fileListInterface.getDownloadMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				downloadSelectedFile();
			}
		});
		
		((JMenuItem) fileListInterface.getStartSyncMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				startManualSynchronization();
			}
		});
		
		((JMenuItem) fileListInterface.getSyncSetupsMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadSyncSetupView();
			}
		});
		
		((JMenuItem) fileListInterface.getPrivacySetupsMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadPrivacySetupView();
			}
		});
		
		((JMenuItem) fileListInterface.getHelpMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				new HelpFrame();
			}
		});
		
		((JMenuItem) fileListInterface.getAboutMenuItem()).addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				new AboutFrame();
			}
		});
	}
	
	/**
	 * Setting the listeners for the for the tray.
	 */
	private void setTrayPopupMenuListesners()
	{
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getSyncItem().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				startManualSynchronization();
				baseFrameController.bringBaseFrameToFront();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getSyncSetups().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadSyncSetupView();
				baseFrameController.bringBaseFrameToFront();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getPrivacySetups().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadPrivacySetupView();
				baseFrameController.bringBaseFrameToFront();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getLogouItem().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				logoutUser();
				baseFrameController.bringBaseFrameToFront();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getUserAboutItem().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				baseFrameController.bringBaseFrameToFront();
				new AboutFrame();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getUserHelpItem().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				baseFrameController.bringBaseFrameToFront();
				new HelpFrame();
			}
		});
		
		((Tray) baseFrameController.getBaseFrame().getTrayIcon()).getUserExitItem().addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
	}
	
	/**
	 * Starting the manual synchronization.
	 */
	private void startManualSynchronization()
	{
		setManualSyncDemand(MANUAL_SYNC_DEMAND);
		startSynchronization();
	}
	
	/**
	 * Starting synchronization.
	 */
	private void startSynchronization()
	{
		synchronized (syncLock)
		{
			if(syncThread == null)
			{
				syncThread = new Thread(new Runnable()
				{
					public void run()
					{
						while(true)
						{
							if(isUserLoggedIn())
							{
								boolean isAutoSync = Boolean.parseBoolean(userProperties.getValue(UserProperties.SYNC_ACTIVE));
								
								if(isAutoSync || getManualSyncDemand() == MANUAL_SYNC_DEMAND)
								{
									setManualSyncDemand(MANUAL_SYNC_CLEAR);
									
									boolean success = true;
									DirectoryPOJO directoryPOJO = new DirectoryPOJO();
									
									try
									{
										directoryPOJO = directoryServices.getSyncDirectory(userProperties.getValue(UserProperties.USERNAME));
									}
									catch (NoConnectionException | WrongUserDataException | DataBaseErrorException e)
									{
										success = false;
									}
									
									if(success)
									{
										String localSyncPath = userProperties.getValue(UserProperties.SYNC_LOCAL_PATH);
										String localSyncDirectory = userProperties.getValue(UserProperties.SYNC_LOCAL_DIRECTORY);
										String serverSyncPath = directoryPOJO.getParrentDirectory();
										String serverSyncDirectory = directoryPOJO.getDirectoryName();
										int syncType = Integer.parseInt(userProperties.getValue(UserProperties.SYNC_TYPE));
										
										success = synchronize(localSyncPath, localSyncDirectory, serverSyncPath, serverSyncDirectory, syncType);
									}
									
									if(isUserLoggedIn())
									{
										SwingUtilities.invokeLater(new Runnable()
										{
											public void run()
											{
												updateLocalDirectoryContent();
												updateServerDirectoryContent();	
											}
										});
										
										if(!success)
										{
											SwingUtilities.invokeLater(new Runnable()
											{
												public void run()
												{
													new GeneralDialog(baseFrameController.getBaseFrame(), "Sync error", "Synchronization failed!", GeneralDialog.ERROR_DIALOG).showDialog();		
												}
											});
										}
									}
								}
							}
							
							try
							{
								Thread.sleep(getManualSyncDemand() * SYNC_CHECK_PERIOD * 1000);
							}
							catch (InterruptedException e) { }
						}
					}
					
				});
				
				syncThread.start();
			}
			else 
			{
				syncThread.interrupt();
			}
		}
	}
	
	/**
	 * Uploading selected files.
	 */
	private void uploadSelectedFile()
	{
		new Thread(new Runnable()
		{
			public void run()
			{
				LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
				ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
				
				if(!localFileListPanel.isCurrentPathCleared())
				{
					if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
					{						
						Object selectedObject = localFileListPanel.getSelectedListItem();
						
						if(selectedObject != null)
						{	
							if(selectedObject.getClass() == LFile.class)
							{
								boolean success = uploadFile(localFileListPanel.getCurrentPath(), serverFileListPanel.getCurrentPath(), ((LFile)selectedObject).getItemName());
								
								if(!success)
								{
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "File upload error", "File upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
								}
							}
							else if (selectedObject.getClass() == LDirectory.class)
							{
								boolean success = uploadDirectory(localFileListPanel.getCurrentPath(), serverFileListPanel.getCurrentPath(), ((LDirectory)selectedObject).getItemName());
							
								if(!success)
								{
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "Directry upload error", "Directry upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
								}
							}
							
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									updateServerDirectoryContent();
									updateLocalDirectoryContent();
								}
							});
						}
						else 
						{
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "Please select a file or a directory!", GeneralDialog.WARNING_DIALOG).showDialog();
								}
							});
						}
					}
					else 
					{
						Object selectedObject = localFileListPanel.getSelectedListItem();
						
						if(selectedObject != null && selectedObject.getClass() == LFile.class)
						{
							String localFileName = ((LFile)selectedObject).getItemName();
							String serverFileName = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
							
							if(localFileName.equals(serverFileName))
							{
								String serverDirectory = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
								
								boolean success = uploadFile(localFileListPanel.getCurrentPath(), serverDirectory, localFileName);
								
								if(!success)
								{
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "File upload error", "File upload failed!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
								}
							}
							else 
							{
								SwingUtilities.invokeLater(new Runnable()
								{
									public void run()
									{
										new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "To a new version, file names must correspond!", GeneralDialog.WARNING_DIALOG).showDialog();
									}
								});
							}
							
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									updateServerDirectoryContent();
									updateLocalDirectoryContent();
								}
							});
						}
						else 
						{
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "Please select a file!", GeneralDialog.WARNING_DIALOG).showDialog();
								}
							});
						}
					}
				}
				else 
				{
					SwingUtilities.invokeLater(new Runnable()
					{
						public void run()
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Upload warning", "You can't upload root directoryes", GeneralDialog.WARNING_DIALOG).showDialog();
						}
					});
				}
			}
			
		}).start();
	}
	
	/**
	 * Downloading selected files.
	 */
	private void downloadSelectedFile()
	{
		new Thread(new Runnable()
		{
			public void run()
			{		
				LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
				ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
				
				if(!localFileListPanel.isCurrentPathCleared())
				{		
					if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
					{							
						Object selectedObject = serverFileListPanel.getSelectedListItem();
						
						if(selectedObject != null)
						{	
							if(selectedObject.getClass() == LFile.class)
							{
								int lastFileVersion = getLastFileVersion(serverFileListPanel.getCurrentPath(), ((LFile) selectedObject).getItemName());
								
								if(lastFileVersion == -1)
								{
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File not found, probably already deleted!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
									
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											updateServerDirectoryContent();
											updateLocalDirectoryContent();
										}
									});
									
									return;
								}
								
								boolean success = downloadFile(localFileListPanel.getCurrentPath(), serverFileListPanel.getCurrentPath(), ((LFile) selectedObject).getItemName(), lastFileVersion);
							
								if(!success)
								{
									
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
								}
							}
							else if (selectedObject.getClass() == LDirectory.class)
							{
								boolean success = downloadDirectory(localFileListPanel.getCurrentPath(), serverFileListPanel.getCurrentPath(), ((LDirectory) selectedObject).getItemName());
							
								if(!success)
								{
									SwingUtilities.invokeLater(new Runnable()
									{
										public void run()
										{
											new GeneralDialog(baseFrameController.getBaseFrame(), "Directory download error", "Directory download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
										}
									});
								}
							}
							
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									updateServerDirectoryContent();
									updateLocalDirectoryContent();
								}
							});
						}
						else 
						{
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Download warning", "Please select a file or a directory!", GeneralDialog.WARNING_DIALOG).showDialog();
								}
							});
						}
					}
					else 
					{
						
						Object selectedObject = serverFileListPanel.getSelectedListItem();
						
						if(selectedObject != null && selectedObject.getClass() == LVFile.class)
						{
							String serverFileName = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
							String serverDirectory = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
							
							boolean success = downloadFile(localFileListPanel.getCurrentPath(), serverDirectory, serverFileName, ((LVFile) selectedObject).getVersionNumber());
							
							if(!success)
							{
								SwingUtilities.invokeLater(new Runnable()
								{
									public void run()
									{
										new GeneralDialog(baseFrameController.getBaseFrame(), "File download error", "File download failed!", GeneralDialog.ERROR_DIALOG).showDialog();
									}
								});
							}
						}
						else 
						{
							SwingUtilities.invokeLater(new Runnable()
							{
								public void run()
								{
									new GeneralDialog(baseFrameController.getBaseFrame(), "Download warning", "Please select a file version!", GeneralDialog.WARNING_DIALOG).showDialog();
								}
							});
						}
						
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								updateServerDirectoryContent();
								updateLocalDirectoryContent();
							}
						});
					}
				}
				else 
				{
					SwingUtilities.invokeLater(new Runnable()
					{
						public void run()
						{
							new GeneralDialog(baseFrameController.getBaseFrame(), "Download warning", "Please select a valid download directory!", GeneralDialog.ERROR_DIALOG).showDialog();
						}
					});
				}
			}
			
		}).start();
	}
	
	/**
	 * Loading synchronization setup view.
	 */
	private void loadSyncSetupView()
	{
		baseFrameController.getSetupController().loadSyncView();
		baseFrameController.getBaseFrame().moveToFront(BaseFrame.SETUP_PANEL);
	}
	
	/**
	 * Loading privacy setup view.
	 */
	private void loadPrivacySetupView()
	{
		baseFrameController.getSetupController().loadPrivacyView();
		baseFrameController.getBaseFrame().moveToFront(BaseFrame.SETUP_PANEL);
	}
	
	/**
	 * Showing a directory content in the local file system.
	 * @param directoryName the name of the directory.
	 */
	private void showLocalDirectoryContent(String directoryName)
	{
		switch (directoryName)
		{
			case ROOT_DIRECTORY:
			{
				displayLocalRoots();
				
			}break;

			case PARENT_DIRECTORY:
			{
				displayLocalParent();
				
			}break;
			
			default:
			{
				displayLocalDirectory(directoryName);
			}
		}
	}
	
	/**
	 * Displaying the root directories of the local file system.
	 */
	private void displayLocalRoots()
	{
		LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
		
		localFileListPanel.clearDocumentPanel();
		localFileListPanel.clearCurrentPath();
		
		for (File root : File.listRoots())
		{			
			String rootPath = root.getPath();
			LDirectory directory = new LDirectory(rootPath);
			directory.addMouseListener(localDirectoryMouseAdapter);
			directory.addDropTargetListener(localDirectoryDropTargetListener);
			localFileListPanel.addDirectory(directory);
		}
		
		localFileListPanel.refreshDocumentPanel();
	}
	
	/**
	 * Navigating to the parent directory in the local file system.
	 */
	private void displayLocalParent()
	{
		LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
		
		if(localFileListPanel.isCurrentPathCleared())
		{
			displayLocalRoots();
		}
		else 
		{
			String parrentPath = stringFormatter.parentDirectoryFormat(localFileListPanel.getCurrentPath(), File.separator);
			File parrentPathFile = new File(parrentPath);
			
			if(parrentPathFile.exists())
			{
				localFileListPanel.setCurrentPath(parrentPath);
				updateLocalDirectoryContent();
			}
			else
			{
				displayLocalRoots();
			}
		}
	}
	
	/**
	 * Displaying the directory content of the local file system.
	 * @param directoryName the name of the directory.
	 */
	private void displayLocalDirectory(String directoryName)
	{
		LocalFileListPanel localFileListPanel = (LocalFileListPanel) fileListInterface.getLocalFileList();
		
		if(!directoryName.equals(""))
		{
			localFileListPanel.appendCurrentPath(directoryName);
		}
		
		File[] directoryContent = new File(localFileListPanel.getCurrentPath()).listFiles();
		
		if(directoryContent == null)
		{
			displayLocalRoots();
		}
		else 
		{
			localFileListPanel.clearDocumentPanel();
			
			LParentDirectory parentDirectory = new LParentDirectory();
			parentDirectory.addMouseListener(localParentDirectoryMouseAdapter);
			localFileListPanel.addParentDirectory(parentDirectory);
			
			for (File file : directoryContent)
			{
				if(!file.isHidden())
				{
					if(file.isDirectory())
					{
						LDirectory directory = new LDirectory(file.getName());
						directory.addMouseListener(localDirectoryMouseAdapter);
						directory.addDragGestureListener(localDirectoryDragGestureListener);
						directory.addDropTargetListener(localDirectoryDropTargetListener);
						localFileListPanel.addDirectory(directory);
					}
				}
			}
			
			for (File file : directoryContent)
			{
				if(!file.isHidden())
				{
					if(file.isFile())
					{
						LFile localFile = new LFile(file.getName());
						localFile.addMouseListener(localFileMouseAdapter);
						localFile.addDragGestureListener(localFileDragGestureListener);
						localFile.addDropTargetListener(localFileDropTargetListener);
						localFileListPanel.addFile(localFile);
					}
				}
			}
			
			localFileListPanel.refreshDocumentPanel();
		}
	}
	
	/**
	 * Updating the local directory content.
	 */
	private void updateLocalDirectoryContent()
	{
		displayLocalDirectory("");	
	}
	
	/**
	 * Showing a directory content on the server.
	 * @param directoryName the name of the directory.
	 */
	private void showServerDirectoryContent(String directoryName)
	{
		switch (directoryName)
		{
			case ROOT_DIRECTORY:
			{
				displayServerRoots();
				
			}break;

			case PARENT_DIRECTORY:
			{
				displayServerParent();
				
			}break;
			
			default:
			{
				displayServerDirectory(directoryName);
			}
		}
	}
	
	/**
	 * Displaying the root directories of the server.
	 */
	private void displayServerRoots()
	{
		ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
		
		serverFileListPanel.clearDocumentPanel();
		serverFileListPanel.clearCurrentPath();
		serverFileListPanel.setDisplayType(ServerFileListPanel.REGULAR_FILE_CONTENT);
		
		DirectoryPOJO serverDirectory;
		
		if(isUserLoggedIn())
		{
			try
			{
				serverDirectory = directoryServices.getBaseDirectory(userProperties.getValue(UserProperties.USERNAME));
			}
			catch (NoConnectionException e)
			{
				SwingUtilities.invokeLater(new Runnable()
				{
					public void run()
					{
						new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();		
					}
				});
				
				serverFileListPanel.refreshDocumentPanel();
				return;
			}
		}
		else 
		{
			serverFileListPanel.refreshDocumentPanel();
			return;
		}		
		
		try
		{
			for (String file : directoryServices.getDirectoriesFromDirectory(serverDirectory))
			{
				LDirectory directory = new LDirectory(file);
				directory.addMouseListener(serverDirectoryMouseAdapter);
				directory.addDragGestureListener(serverDirectoryDragGestureListener);
				directory.addDropTargetListener(serverDirectoryDropTargetListener);
				serverFileListPanel.addDirectory(directory);
			}
		}
		catch (NoConnectionException  e)
		{
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();		
				}
			});
			
			serverFileListPanel.refreshDocumentPanel();
			return;
		}
		catch (DataBaseErrorException e) { }
		
		try
		{
			for (String file : fileServices.getFilesFromDirectory(serverDirectory))
			{
				LFile lFile = new LFile(file);
				lFile.addMouseListener(serverFileMouseAdapter);
				lFile.addDragGestureListener(serverFileDragGestureListener);
				lFile.addDropTargetListener(serverFileDropTargetListener);
				serverFileListPanel.addFile(lFile);
			}
		}
		catch (NoConnectionException e)
		{
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();		
				}
			});
			
			serverFileListPanel.refreshDocumentPanel();
			return;
		}
		catch (DataBaseErrorException e) { }
		
		serverFileListPanel.refreshDocumentPanel();
	}
	
	/**
	 * Navigating to the parent directory on the server.
	 */
	private void displayServerParent()
	{
		ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
		
		String parrentPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
		serverFileListPanel.setCurrentPath(parrentPath);
		
		if(serverFileListPanel.isCurrentPathCleared())
		{
			displayServerRoots();
		}
		else 
		{
			String parrentDirectory = stringFormatter.getLastDirectoryInPath(parrentPath, DirectoryCLTServices.separator);
			parrentPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
			serverFileListPanel.setCurrentPath(parrentPath);
			
			displayServerDirectory(parrentDirectory);
		}
		
	}
	
	/**
	 * Displaying the directory content of the server.
	 * @param directoryName the name of the directory.
	 */
	private void displayServerDirectory(String directoryName)
	{
		ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
				
		DirectoryPOJO serverDirectory = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			serverDirectory.setOwner(userProperties.getValue(UserProperties.USERNAME));
			serverDirectory.setDirectoryName(directoryName);
			serverDirectory.setParrentDirectory(serverFileListPanel.getCurrentPath());
		}
		else 
		{
			return;
		}
		
		serverFileListPanel.clearDocumentPanel();
		serverFileListPanel.appendCurrentPath(directoryName);
		serverFileListPanel.setDisplayType(ServerFileListPanel.REGULAR_FILE_CONTENT);
		
		
		LParentDirectory parentDirectory = new LParentDirectory();
		parentDirectory.addMouseListener(serverParentDirectoryMouseAdapter);
		serverFileListPanel.addParentDirectory(parentDirectory);
		
		try
		{
			for (String file : directoryServices.getDirectoriesFromDirectory(serverDirectory))
			{
				LDirectory directory = new LDirectory(file);
				directory.addMouseListener(serverDirectoryMouseAdapter);
				directory.addDragGestureListener(serverDirectoryDragGestureListener);
				directory.addDropTargetListener(serverDirectoryDropTargetListener);
				serverFileListPanel.addDirectory(directory);
			}
		}
		catch (NoConnectionException e)
		{
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();		
				}
			});
			
			serverFileListPanel.refreshDocumentPanel();
			return;
		}
		catch (DataBaseErrorException e) { }
		
		try
		{
			for (String file : fileServices.getFilesFromDirectory(serverDirectory))
			{
				LFile lFile = new LFile(file);
				lFile.addMouseListener(serverFileMouseAdapter);
				lFile.addDragGestureListener(serverFileDragGestureListener);
				lFile.addDropTargetListener(serverFileDropTargetListener);
				serverFileListPanel.addFile(lFile);
			}
		}
		catch (NoConnectionException e)
		{
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();		
				}
			});
			
			serverFileListPanel.refreshDocumentPanel();
			return;
		}
		catch (DataBaseErrorException e) { }
		
		serverFileListPanel.refreshDocumentPanel();
	}

	/**
	 * Updating the server directory content.
	 */
	private void updateServerDirectoryContent()
	{
		ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
		
		if(serverFileListPanel.getDisplayType() == ServerFileListPanel.REGULAR_FILE_CONTENT)
		{
			if(!serverFileListPanel.isCurrentPathCleared())
			{
				String parrentPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
				String parrentDirectory = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
				serverFileListPanel.setCurrentPath(parrentPath);
				displayServerDirectory(parrentDirectory);
			}
			else 
			{
				displayServerRoots();
			}
		}
		else 
		{
			String fileName = stringFormatter.getLastDirectoryInPath(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
			String parrentPath = stringFormatter.parentDirectoryFormat(serverFileListPanel.getCurrentPath(), DirectoryCLTServices.separator);
			serverFileListPanel.setCurrentPath(parrentPath);
			displayServerFileVersions(fileName);
		}
	}
	
	/**
	 * Show the file versions, of the selected file.
	 * @param fileName the name of the file.
	 */
	private void displayServerFileVersions(String fileName)
	{
		ServerFileListPanel serverFileListPanel = (ServerFileListPanel) fileListInterface.getServerFileList();
		
		FilePOJO filePOJO = new FilePOJO();;
		
		if(isUserLoggedIn())
		{
			filePOJO.setFileName(fileName);
			filePOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			filePOJO.setDirectoryName(serverFileListPanel.getCurrentPath());
		}
		else 
		{
			return;
		}
		
		serverFileListPanel.clearDocumentPanel();
		serverFileListPanel.appendCurrentPath(fileName);
		serverFileListPanel.setDisplayType(ServerFileListPanel.VERSION_FILE_CONTENT);
		
		LParentDirectory parentDirectory = new LParentDirectory();
		parentDirectory.addMouseListener(serverParentDirectoryMouseAdapter);
		serverFileListPanel.addParentDirectory(parentDirectory);
		
		try
		{
			ArrayList<Integer> fileVersionList = fileServices.getAllFileVersions(filePOJO);
			
			for (Integer version : fileVersionList)
			{
				LVFile lvFile = new LVFile(version);
				lvFile.addDragGestureListener(serverFileVersionDragGestureListener);
				lvFile.addDropTargetListener(serverFileDropTargetListener);
				serverFileListPanel.addFile(lvFile);
			}
			
		}
		catch (NoConnectionException e)
		{
			SwingUtilities.invokeLater(new Runnable()
			{
				public void run()
				{
					new GeneralDialog(baseFrameController.getBaseFrame(), "Connection error", "Connection dropped!", GeneralDialog.WARNING_DIALOG).showDialog();
				}
			});
			
			serverFileListPanel.refreshDocumentPanel();
			return;
		}
		catch (FileOperationException | DataBaseErrorException e) { }
		
		serverFileListPanel.refreshDocumentPanel();
	}
	
	/**
	 * Opening a local file, with the system default application, if it possible.
	 * @param directory the directory name, where the file is.
	 * @param fileName the name of file.
	 * @return true on success, false otherwise.
	 */
	private boolean openLocalFile(String directory, String fileName)
	{
		File file = new File(directory + fileName);
		
		if(!file.exists())
		{
			return false;
		}
		
		if (!Desktop.isDesktopSupported()) 
		{
			return false;
		}

		Desktop desktop = Desktop.getDesktop();
		  
		if (!desktop.isSupported(Desktop.Action.EDIT)) 
		{
			return false;
		}

		try 
		{
			desktop.open(file);
		} 
		catch (Exception e) 
		{
			return false;
		}

		return true;
	}
	
	
	/**
	 * Upload a file to the server.
	 * @param localDirectory the local directory name where the file is.
	 * @param serverDirectory the selected server directory.
	 * @param fileName the name of the file.
	 * @return true if the upload successful, false otherwise.
	 */
	private boolean uploadFile(String localDirectory, String serverDirectory, String fileName)
	{
		File selectedFile = new File(localDirectory + fileName);
		
		FilePOJO file;
		
		if(isUserLoggedIn())
		{
			file = new FilePOJO();
			file.setFileName(fileName);							
			file.setOwner(userProperties.getValue(UserProperties.USERNAME));
			file.setDirectoryName(serverDirectory);
		}
		else 
		{
			return false;
		}
		
		try
		{
			file.setFileInputStream(new FileInputStream(selectedFile));
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		ListItem observer = new ListItem(FileTransferObserver.UPLOAD);		
		observer.setFileName(selectedFile.getName());
		observer.setFileSize(selectedFile.length());

		((ScrollList) fileListInterface.getBottomScrollList()).addItem((ListItem) observer);

		try
		{
			fileServices.uploadFile(file, observer);
		}
		catch (TransferInterruptedException | FileUploadException e)
		{
			try
			{
				//TODO delete only the last file version.
				fileServices.deleteAllFileVersions(file);
			}
			catch (NoConnectionException | FileOperationException | DataBaseErrorException ex) { }
			
			return false;
		}
		
		try
		{
			Thread.sleep(TRANSFER_WAIT * 1000);
		}
		catch (InterruptedException e) { }
		
		return true;
	}
	
	/**
	 * Upload a directory to the server.
	 * @param localDirectory the local directory name where the file is.
	 * @param serverDirectory the selected server directory.
	 * @param directoryName the name of the directory.
	 * @return true if the upload successful, false otherwise.
	 */
	private boolean uploadDirectory(String localDirectory, String serverDirectory, String directoryName)
	{
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setDirectoryName(directoryName);
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setParrentDirectory(serverDirectory);
		}
		else 
		{
			return false;
		}
		
		File[] fileList = new File(localDirectory + directoryName).listFiles();
		
		if(fileList != null)
		{
			try
			{
				directoryServices.createDirectory(directoryPOJO);
			}
			catch (NoConnectionException | DataBaseErrorException e) 
			{
				return false;
			}
			catch (DirectoryOperationException e) { }
			
			for (File aFile : fileList)
			{
				if(aFile.isDirectory())
				{
					if(!uploadDirectory(localDirectory + directoryName + File.separator, serverDirectory + directoryName + DirectoryCLTServices.separator, aFile.getName()))
					{
						return false;
					}
				}
			}
			
			for (File aFile : fileList)
			{
				if(!aFile.isDirectory())
				{
					if(!uploadFile(localDirectory + directoryName + File.separator, serverDirectory + directoryName + DirectoryCLTServices.separator, aFile.getName()))
					{
						return false;
					}
				}
			}
		}
		else 
		{
			return false;
		}
		
		return true;
	}
	
	/**
	 * Downloading a file.
	 * @param localDirectory the local directory name.
	 * @param serverDirectory the server directory name.
	 * @param fileName the file name.
	 * @param fileVersion the file version.
	 * @return true on success, falso otherwise.
	 */
	private boolean downloadFile(String localDirectory, String serverDirectory, String fileName, int fileVersion)
	{		
		FilePOJO file = new FilePOJO();
		
		if(isUserLoggedIn())
		{
			file.setFileName(fileName);
			file.setOwner(userProperties.getValue(UserProperties.USERNAME));
			file.setDirectoryName(serverDirectory);
			file.setVersion(fileVersion);
		}
		else 
		{
			return false;
		}		
		
		ListItem observer = new ListItem(FileTransferObserver.DOWNLOAD);
		observer.setFileName(fileName);
		
		try
		{
			observer.setFileSize(fileServices.getFileSize(file));
		}
		catch (NoConnectionException | FileOperationException | DataBaseErrorException e)
		{
			return false;
		} 
		
		try
		{
			file.setFileOutputStream(new FileOutputStream(localDirectory + fileName));
		}
		catch (FileNotFoundException e)
		{
			return false;
		}		
					
		((ScrollList) fileListInterface.getBottomScrollList()).addItem((ListItem) observer);
					
		try
		{
			fileServices.downloadFile(file, observer);
		}
		catch (TransferInterruptedException | FileDownloadException e)
		{
			deleteLocalFile(localDirectory, fileName);
			return false;
		}
		
		try {
			long fileUploadDate = fileServices.getFileUploadDate(file);
			new File(localDirectory + fileName).setLastModified(fileUploadDate);
		} catch (Exception e) {
			return false;
		}
		
		try
		{
			Thread.sleep(TRANSFER_WAIT * 1000);
		}
		catch (InterruptedException e) { }
		
		return true;
	}
	
	/**
	 * Downloading a directory.
	 * @param localDirectory the local directory.
	 * @param serverDirectory the server directory.
	 * @param directoryName the name of the directory.
	 * @return true on successfully download.
	 */
	private boolean downloadDirectory(String localDirectory, String serverDirectory, String directoryName)
	{
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setDirectoryName(directoryName);
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setParrentDirectory(serverDirectory);
		}
		else 
		{
			return false;
		}
		
		ArrayList<String> directoryList;
		
		try
		{
			directoryList = directoryServices.getDirectoriesFromDirectory(directoryPOJO);
		}
		catch (NoConnectionException | DataBaseErrorException e)
		{
			return false;
		}
		
		makeNewLocalDirectory(localDirectory, directoryName);
		
		for (String aDirectory : directoryList)
		{
			if(!downloadDirectory(localDirectory + directoryName + File.separator, serverDirectory + directoryName + DirectoryCLTServices.separator, aDirectory))
			{
				return false;
			}
		}
		
		ArrayList<String> fileList;
		
		try
		{
			fileList = fileServices.getFilesFromDirectory(directoryPOJO);
		}
		catch (NoConnectionException | DataBaseErrorException e)
		{
			return false;
		}
		
		for (String aFile : fileList)
		{
			int lastFileVersion = getLastFileVersion(serverDirectory + directoryName + DirectoryCLTServices.separator, aFile);
			
			if(lastFileVersion == -1)
			{
				return false;
			}
			
			if(!downloadFile(localDirectory + directoryName + File.separator, serverDirectory + directoryName + DirectoryCLTServices.separator, aFile, lastFileVersion))
			{
				return false;
			}
		}

		return true;
	}
	
	/**
	 * Creating new local directory in client part
	 * @param path where to create the new directory
	 * @param name is new directory name
	 * @return true on success
	 */
	private boolean makeNewLocalDirectory(String path, String name)
	{
		return (new File(path + name)).mkdir();
	}
	
	/**
	 * Delete a local directory, and its content (recursively).
	 * @param path where is the directory.
	 * @param name of directory.
	 * @return true on success.
	 */
	private boolean deleteLocalDirectory(String path, String name) 
	{
	      File file = new File(path + name);
	      
	      if(!file.exists()) 
	      {
	          return true;
	      }
	      
	      if(!file.isDirectory())
	      {
	    	  return file.delete();
	      }

	      String[] list = file.list();
	      
	      for (int i = 0; i < list.length; i++) 
	      {
	    	  if(!deleteLocalDirectory(path + name + File.separator, list[i]))
	    	  {
	    		  return false;
	    	  }
	      }

	      return file.delete();
	  }
	
	/**
	 * Delete a local file.
	 * @param path where is the file.
	 * @param name of directory.
	 * @return true on success.
	 */
	private boolean deleteLocalFile(String path, String name)
	{
		return (new File(path + name)).delete();
	}
	
	/**
	 * Making a new server directory.
	 * @param path the directory path.
	 * @param name the name of the new directory.
	 * @return true on success, false otherwise.
	 */
	private boolean makeNewServerDirectory(String path, String name)
	{
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setDirectoryName(name);
			directoryPOJO.setParrentDirectory(path);
		}
		else 
		{
			return false;
		}
		
		try
		{
			directoryServices.createDirectory(directoryPOJO);
			return true;
		}
		catch (NoConnectionException | DirectoryOperationException | DataBaseErrorException ex)
		{
			return false;
		}
	}
	
	/**
	 * Delete a server directory and its content (recursively).
	 * @param path where is the directory.
	 * @param name the directory name.
	 * @return true on success, false otherwise.
	 */
	private boolean deleteServerDirectory(String path, String name)
	{
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setDirectoryName(name);
			directoryPOJO.setParrentDirectory(path);
		}
		else 
		{
			return false;
		}
		
		try
		{
			ArrayList<String> directoryList = directoryServices.getDirectoriesFromDirectory(directoryPOJO);
			
			for (String aDirectory : directoryList)
			{
				if(!deleteServerDirectory(path + name + DirectoryCLTServices.separator, aDirectory))
				{
					return false;
				}
			}
			
		}
		catch (NoConnectionException | DataBaseErrorException e)
		{
			return false;
		}
		
		
		try
		{
			ArrayList<String> fileList = fileServices.getFilesFromDirectory(directoryPOJO);
			
			FilePOJO filePOJO = new FilePOJO();
			
			if(isUserLoggedIn())
			{
				filePOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
				filePOJO.setDirectoryName(path + name + DirectoryCLTServices.separator);
			}
			else 
			{
				return false;
			}
			
			for (String aFile : fileList)
			{
				filePOJO.setFileName(aFile);
				fileServices.deleteAllFileVersions(filePOJO);
			}
		}
		catch (NoConnectionException | DataBaseErrorException | FileOperationException e)
		{
			return false;
		}
		
		
		try
		{
			directoryServices.deleteDirectory(directoryPOJO);
		}
		catch (NoConnectionException | DirectoryOperationException | DataBaseErrorException e)
		{
			return false;
		}
		
		return true;
	}

	/**
	 * Delete a file on the server.
	 * @param path where is the file.
	 * @param name the file name.
	 * @return true on success, false otherwise.
	 */
	private boolean deleteServerFile(String path, String name)
	{
		FilePOJO filePOJO = new FilePOJO();
		
		if(isUserLoggedIn())
		{
			filePOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			filePOJO.setFileName(name);
			filePOJO.setDirectoryName(path);
		}
		else 
		{
			return false;
		}

		try
		{
			fileServices.deleteAllFileVersions(filePOJO);
		}
		catch (NoConnectionException | FileOperationException | DataBaseErrorException e)
		{
			return false;
		}
		
		return true;
	}

	/**
	 * Delete a server file version.
	 * @param path where is the file.
	 * @param name the file name.
	 * @param versionNumber the selected version number.
	 * @return true on success, false otherwise.
	 */
	private boolean deleteServerFileVersion(String path, String name, int versionNumber)
	{
		FilePOJO filePOJO = new FilePOJO();
		
		if(isUserLoggedIn())
		{
			filePOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			filePOJO.setFileName(name);
			filePOJO.setDirectoryName(path);
			filePOJO.setVersion(versionNumber);
		}
		else 
		{
			return false;
		}
		
		try
		{
			fileServices.deleteFile(filePOJO);
		}
		catch (NoConnectionException | FileOperationException | DataBaseErrorException e)
		{
			return false;
		}
		
		return true;
	}
	
	/**
	 * Synchronize a folder with a selected folder on the server.
	 * @param localPath the local folder path.
	 * @param localDirectory the local directory name.
	 * @param serverPath the server folder path.
	 * @param serverDirectory the server directory name.
	 * @return true on success.
	 */
	private boolean synchronize(String localPath, String localDirectory, String serverPath, String serverDirectory, int syncType)
	{
		switch(syncType)
		{
			case ONE_WAY_SYNC:
			{
				boolean downloadSuccess = synchronizeDownload(localPath, localDirectory, serverPath, serverDirectory);
				
				if(downloadSuccess)
				{
					return synchronizeDelete(localPath, localDirectory, serverPath, serverDirectory);
				}
				
				return false;
			}
			
			case TWO_WAY_SYNC:
			{
				boolean downloadSuccess = synchronizeDownload(localPath, localDirectory, serverPath, serverDirectory);
				
				if(downloadSuccess)
				{
					return synchronizeUpload(localPath, localDirectory, serverPath, serverDirectory);
				}
				
				return false;
			}
		}
		
		return false;
	}
	
	/**
	 * Downloading the files and directories from the synchronized server folder if not exists in the local folder.
	 * @param localPath the local folder path.
	 * @param localDirectory the local directory name.
	 * @param serverPath the server folder path.
	 * @param serverDirectory the server directory name.
	 * @return true on success.
	 */
	private boolean synchronizeDownload(String localPath, String localDirectory, String serverPath, String serverDirectory)
	{
		ArrayList<String> localDirectoryes;
		ArrayList<String> serverDirectoryes;
		
		try
		{
			localDirectoryes = getLocalDirectoryes(localPath, localDirectory);
			serverDirectoryes = getServerDirectoryes(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		
		for (String currDirectory : serverDirectoryes)
		{
			if(localDirectoryes.contains(currDirectory))
			{
				boolean success = synchronizeDownload(localPath + localDirectory + File.separator, currDirectory, serverPath + serverDirectory + DirectoryCLTServices.separator, currDirectory);
			
				if(!success)
				{
					return false;
				}
			}
			else 
			{
				boolean success = downloadDirectory(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currDirectory);
				
				if(!success)
				{
					return false;
				}
			}
		}
		
		ArrayList<String> localFiles;
		ArrayList<String> serverFiles;
		
		try
		{
			localFiles = getLocalFiles(localPath, localDirectory);
			serverFiles = getServerFiles(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		
		for (String currFile : serverFiles)
		{
			if(!localFiles.contains(currFile))
			{
				int lastFileVersion = getLastFileVersion(serverPath + serverDirectory + DirectoryCLTServices.separator, currFile);
				
				if(lastFileVersion == -1)
				{
					return false;
				}
				
				boolean success = downloadFile(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currFile, lastFileVersion);
				
				if(!success)
				{
					return false;
				}
			} else {
				//TODO check upload date
				
				if(isUserLoggedIn())
				{
					int lastFileVersion = getLastFileVersion(serverPath + serverDirectory + DirectoryCLTServices.separator, currFile);
					
					FilePOJO file = new FilePOJO();
					file.setFileName(currFile);
					file.setOwner(userProperties.getValue(UserProperties.USERNAME));
					file.setDirectoryName(serverPath + serverDirectory + DirectoryCLTServices.separator);
					file.setVersion(lastFileVersion);
					
					try {
						File localFile = new File(localPath + localDirectory + File.separator + currFile);
						
						long fileUploadDate = fileServices.getFileUploadDate(file);
						long lastModifiedDate = localFile.lastModified();
						
						if(fileUploadDate > lastModifiedDate) {
							boolean success = downloadFile(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currFile, lastFileVersion);
							localFile.setLastModified(fileUploadDate);
							
							if(!success)
							{
								return false;
							}
						}
					} catch (Exception e) {
						return false;
					}
				}
			}
		}
		
		return true;
	}
	
	
	/**
	 * Uploading the local files, which do not exists in the server.
	 * @param localPath the local folder path.
	 * @param localDirectory the local directory name.
	 * @param serverPath the server folder path.
	 * @param serverDirectory the server directory name.
	 * @return true on success.
	 */
	private boolean synchronizeUpload(String localPath, String localDirectory, String serverPath, String serverDirectory)
	{
		ArrayList<String> localDirectoryes;
		ArrayList<String> serverDirectoryes;
		
		try
		{
			localDirectoryes = getLocalDirectoryes(localPath, localDirectory);
			serverDirectoryes = getServerDirectoryes(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		for (String currDirectory : localDirectoryes)
		{
			if(serverDirectoryes.contains(currDirectory))
			{
				boolean success = synchronizeUpload(localPath + localDirectory + File.separator, currDirectory, serverPath + serverDirectory + DirectoryCLTServices.separator, currDirectory);
			
				if(!success)
				{
					return false;
				}
			}
			else 
			{
				boolean success = uploadDirectory(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currDirectory);
				
				if(!success)
				{
					return false;
				}
			}
		}
		
		ArrayList<String> localFiles;
		ArrayList<String> serverFiles;
		
		try
		{
			localFiles = getLocalFiles(localPath, localDirectory);
			serverFiles = getServerFiles(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		for (String currFile : localFiles)
		{
			if(!serverFiles.contains(currFile))
			{
				boolean success = uploadFile(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currFile);
				
				if(!success)
				{
					return false;
				}
			} else {
				//TODO check upload date
				
				if(isUserLoggedIn())
				{
					int lastFileVersion = getLastFileVersion(serverPath + serverDirectory + DirectoryCLTServices.separator, currFile);
					
					FilePOJO file = new FilePOJO();
					file.setFileName(currFile);
					file.setOwner(userProperties.getValue(UserProperties.USERNAME));
					file.setDirectoryName(serverPath + serverDirectory + DirectoryCLTServices.separator);
					file.setVersion(lastFileVersion);
					
					try {
						File localFile = new File(localPath + localDirectory + File.separator + currFile);
						
						long fileUploadDate = fileServices.getFileUploadDate(file);
						long lastModifiedDate = localFile.lastModified();
						
						if(fileUploadDate < lastModifiedDate) {
							fileServices.deleteFile(file);
							boolean success = uploadFile(localPath + localDirectory + File.separator, serverPath + serverDirectory + DirectoryCLTServices.separator, currFile);
							file.setVersion(getLastFileVersion(serverPath + serverDirectory + DirectoryCLTServices.separator, currFile));
							localFile.setLastModified(fileServices.getFileUploadDate(file));
							
							if(!success)
							{
								return false;
							}
						}
					} catch (Exception e) {
						return false;
					}
				}
			}
		}
		
		return true;
	}
	
	/**
	 * Deleting the files and directories from the local folder if the server does not contain its.
	 * @param localPath the local folder path.
	 * @param localDirectory the local directory name.
	 * @param serverPath the server folder path.
	 * @param serverDirectory the server directory name.
	 * @return true on success.
	 */	
	private boolean synchronizeDelete(String localPath, String localDirectory, String serverPath, String serverDirectory)
	{
		ArrayList<String> localDirectoryes;
		ArrayList<String> serverDirectoryes;
		
		try
		{
			localDirectoryes = getLocalDirectoryes(localPath, localDirectory);
			serverDirectoryes = getServerDirectoryes(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		for (String currDirectory : localDirectoryes)
		{
			if(serverDirectoryes.contains(currDirectory))
			{
				boolean success = synchronizeDelete(localPath + localDirectory + File.separator, currDirectory, serverPath + serverDirectory + DirectoryCLTServices.separator, currDirectory);
			
				if(!success)
				{
					return false;
				}
			}
			else 
			{
				boolean success = deleteLocalDirectory(localPath + localDirectory + File.separator, currDirectory);
				
				if(!success)
				{
					return false;
				}
			}
		}
		
		ArrayList<String> localFiles;
		ArrayList<String> serverFiles;
		
		try
		{
			localFiles = getLocalFiles(localPath, localDirectory);
			serverFiles = getServerFiles(serverPath, serverDirectory);
		}
		catch (FileNotFoundException e)
		{
			return false;
		}
		
		for (String currFile : localFiles)
		{
			if(!serverFiles.contains(currFile))
			{
				boolean success = deleteLocalFile(localPath + localDirectory + File.separator, currFile);
				
				if(!success)
				{
					return false;
				}
			}
		}
		
		return true;
	}
	
	
	/**
	 * Getting the local directories from a folder.
	 * @param path the folders path.
	 * @param directoryName the directory name.
	 * @return the list of directories.
	 * @throws FileNotFoundException if the file not exist.
	 */
	public ArrayList<String> getLocalDirectoryes(String path, String directoryName) throws FileNotFoundException
	{
		ArrayList<String> directoryList = new ArrayList<String>();
		File[] fileList = new File(path + directoryName).listFiles();
		
		if(fileList != null)
		{
			for (File file : fileList)
			{
				if(!file.isHidden() && file.isDirectory())
				{
					directoryList.add(file.getName());
				}
			}
		}
		else 
		{
			throw new FileNotFoundException();
		}
		
		return directoryList;
	}
	
	/**
	 * Getting the server directories from a folder.
	 * @param path the folders path.
	 * @param directoryName the directory name.
	 * @return the list of directories.
	 * @throws FileNotFoundException 
	 */
	public ArrayList<String> getServerDirectoryes(String path, String directoryName) throws FileNotFoundException
	{
		ArrayList<String> directoryList = new ArrayList<String>();
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setDirectoryName(directoryName);
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setParrentDirectory(path);
		}
		else 
		{
			return directoryList;
		}
		
		try
		{
			directoryList = directoryServices.getDirectoriesFromDirectory(directoryPOJO);
		}
		catch (NoConnectionException | DataBaseErrorException e) 
		{ 
			throw new FileNotFoundException();
		}
		
		return directoryList;
	}

	
	/**
	 * Getting the local files from a folder.
	 * @param path the folders path.
	 * @param directoryName the directory name.
	 * @return the list of files.
	 * @throws FileNotFoundException if the file not exist.
	 */
	private ArrayList<String> getLocalFiles(String path, String directoryName) throws FileNotFoundException
	{
		ArrayList<String> filesList = new ArrayList<String>();
		File[] fileList = new File(path + directoryName).listFiles();
		
		if(fileList != null)
		{
			for (File file : fileList)
			{
				if(!file.isHidden() && file.isFile())
				{
					filesList.add(file.getName());
				}
			}
		}
		else 
		{
			throw new FileNotFoundException();
		}
		
		return filesList;
	} 
	
	/**
	 * Getting the server files from a folder.
	 * @param path the folders path.
	 * @param directoryName the directory name.
	 * @return the list of files.
	 * @throws FileNotFoundException if the file not exist.
	 */
	private ArrayList<String> getServerFiles(String path, String directoryName) throws FileNotFoundException
	{
		DirectoryPOJO directoryPOJO = new DirectoryPOJO();
		ArrayList<String> fileList = new ArrayList<String>();
		
		if(isUserLoggedIn())
		{
			directoryPOJO.setDirectoryName(directoryName);
			directoryPOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			directoryPOJO.setParrentDirectory(path);
		}
		else 
		{
			return fileList;
		}
		
		try
		{
			fileList = fileServices.getFilesFromDirectory(directoryPOJO);
		}
		catch (NoConnectionException | DataBaseErrorException e) 
		{ 
			throw new FileNotFoundException();
		}
		
		return fileList;
	}
	
	/**
	 * Getting the last file version number of a file.
	 * @param path the file path.
	 * @param name the file name.
	 * @return the last file version number.
	 */
	private int getLastFileVersion(String path, String name)
	{
		FilePOJO filePOJO = new FilePOJO();
		
		if(isUserLoggedIn())
		{			
			filePOJO.setOwner(userProperties.getValue(UserProperties.USERNAME));
			filePOJO.setFileName(name);
			filePOJO.setDirectoryName(path);
		}
		else 
		{
			return -1;
		}
		
		try
		{
			return fileServices.getLastFileVersionNumber(filePOJO);
		}
		catch (NoConnectionException | FileOperationException | DataBaseErrorException e)
		{
			return -1;
		}
	}
	
	/**
	 * Setting on the manual synchronization demand.
	 * @param manualSyncDemanValue the manual synchronization demand value.
	 */
	private void setManualSyncDemand(int manualSyncDemanValue)
	{
		synchronized (manualSyncDemandLock)
		{
			manualSyncDemand = manualSyncDemanValue;
		}
	}
	
	/**
	 * Getting the manual synchronization demand.
	 * @return the manual synchronization demand value.
	 */
	private int getManualSyncDemand()
	{
		synchronized (manualSyncDemandLock)
		{
			return manualSyncDemand;
		}
	}
	
	/**
	 * Setting on that user logged in or not.
	 * @param isUserLoggedIn the user logging in value.
	 */
	private void setUserLoggedIn(boolean isUserLoggedIn)
	{
		synchronized(loginLock)
		{
			this.isUserLoggedIn = isUserLoggedIn;
		}
	}
	
	/**
	 * Getting that user is logged in or not.
	 * @return user status, what is logged in or not logged in.
	 */
	private boolean isUserLoggedIn()
	{
		synchronized(loginLock)
		{
			return isUserLoggedIn;
		}
	}
	
	/**
	 * Logging on the user.
	 */
	public void logonUser()
	{
		setUserLoggedIn(true);
		startSynchronization();
		
		showLocalDirectoryContent(ROOT_DIRECTORY);
		showServerDirectoryContent(ROOT_DIRECTORY);	
		
		((Tray)baseFrameController.getBaseFrame().getTrayIcon()).setPopUpMenuType(Tray.USER_POPUP_MENU);
		
		((ScrollList) fileListInterface.getBottomScrollList()).destroyAllItems();
	}
	
	/**
	 * Logout user.
	 */
	public void logoutUser()
	{
		setManualSyncDemand(MANUAL_SYNC_CLEAR);
		setUserLoggedIn(false);
		
		((Tray)baseFrameController.getBaseFrame().getTrayIcon()).setPopUpMenuType(Tray.GUEST_POPUP_MENU);
		
		((ScrollList) fileListInterface.getBottomScrollList()).destroyAllItems();
		baseFrameController.getBaseFrame().moveToFront(BaseFrame.LOGON_PANEL);
	}
}
